<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>打印水牌</title>
    <script>
      const paperTypes = {
        a4: {
          width: 794,
          height: 1123,
          mmWidth: 210,
          mmHeight: 297,
          name: "A4",
        },
        a5: {
          width: 559,
          height: 794,
          mmWidth: 148,
          mmHeight: 210,
          name: "A5",
        },
        a3: {
          width: 1123,
          height: 1587,
          mmWidth: 297,
          mmHeight: 420,
          name: "A3",
        },
        b5: {
          width: 665,
          height: 945,
          mmWidth: 176,
          mmHeight: 250,
          name: "B5",
        },
        letter: {
          width: 816,
          height: 1056,
          mmWidth: 216,
          mmHeight: 279,
          name: "Letter",
        },
        legal: {
          width: 816,
          height: 1344,
          mmWidth: 216,
          mmHeight: 356,
          name: "Legal",
        },
        custom: {
          width: 794,
          height: 1123,
          mmWidth: 210,
          mmHeight: 297,
          name: "自定义",
        },
      };
      var pos = {
          ft: 156, //默认字体大小
          paperx: paperTypes.a4.width, //纸张默认宽度 (A4宽度-边距)
          papery: paperTypes.a4.height, //纸张默认高度 (A4高度-边距)
          poslx: 400, //名称横向默认调整位置
          posly: 900, //名称竖向默认调整位置
          pos1x: 50, //logo1横向默认调整位置
          pos1y: 700, //logo1竖向默认调整位置
          zoom1: 1, //logo1缩放比例
          pos2x: 220, //logo2横向默认调整位置
          pos2y: 710, //logo2竖向默认调整位置
          zoom2: 1, //logo2缩放比例
          offsetx: 0, //倒影的默认横向偏移长度
          offsety: 0, //倒影的默认竖向偏移长度
        },
        els = Object.assign({}, pos);
      els.fm = "微软雅黑"; //默认字体
      els.lst = ["张三", "李四李四", "王小二"]; //预设参考字符
      els.lg1 = new Image(); //logo元素1，勿动
      els.lg2 = new Image(); //logo元素2，勿动
      els.st = "normal"; //默认字体风格
      els.wt = "400"; //默认字体粗细
      els.hasLogo1 = false; //标记是否选择了logo1
      els.hasLogo2 = false; //标记是否选择了logo2
      // 修改纸张选择下拉框的选项文本，显示毫米尺寸
      function initPaperTypeSelect() {
        const paperTypeSelect = document.getElementById("paperType");
        paperTypeSelect.innerHTML = "";

        for (const [key, paper] of Object.entries(paperTypes)) {
          const option = document.createElement("option");
          option.value = key;
          if (key === "custom") {
            option.textContent = `${paper.name}`;
          } else {
            option.textContent = `${paper.name} (${paper.mmWidth}×${paper.mmHeight}mm)`;
          }
          paperTypeSelect.appendChild(option);
        }

        // 设置默认值
        paperTypeSelect.value = "a4";
      }
    </script>
    <style media="print">
      @page {
        size: A4 portrait;
        margin: 0;
      }

      body {
        margin: 0;
        padding: 0;
      }

      .print-page {
        width: 100%;
        height: 100vh;
        display: flex;
        justify-content: center;
        align-items: center;
        page-break-after: always;
      }

      .print-page:last-child {
        page-break-after: auto;
      }

      .print-content {
        width: 100%;
        height: 100%;
      }
    </style>
    <style>
      body {
        font-family: "Microsoft YaHei", sans-serif;
        padding: 20px;
        background-color: #f5f5f5;
      }

      .container {
        max-width: 1200px;
        margin: 0 auto;
        background: white;
        padding: 20px;
        border-radius: 8px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
      }

      h1 {
        text-align: center;
        color: #333;
        margin-bottom: 20px;
      }

      .control-panel {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
        gap: 15px;
        margin-bottom: 20px;
      }

      .control-group {
        background: #f9f9f9;
        padding: 15px;
        border-radius: 6px;
        border: 1px solid #eee;
      }

      .control-group h3 {
        margin-top: 0;
        margin-bottom: 15px;
        padding-bottom: 8px;
        border-bottom: 1px solid #ddd;
        color: #444;
      }

      #mingdan {
        margin-top: 0;
        margin-bottom: 15px;
        padding-bottom: 8px;
        border-bottom: 1px solid #ddd;
        color: #444;
      }

      label {
        display: inline-block;
        width: 80px;
        font-weight: bold;
        color: #555;
      }

      input[type="range"] {
        width: 150px;
        vertical-align: middle;
      }

      input[type="file"] {
        width: 180px;
      }

      select {
        padding: 5px;
        border-radius: 4px;
        border: 1px solid #ccc;
      }

      .button-group {
        text-align: center;
        margin: 20px 0;
      }

      button {
        padding: 10px 20px;
        margin: 0 10px;
        background: #4a6ee0;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
        font-size: 16px;
        transition: background 0.3s;
      }

      button:hover {
        background: #3a5ecc;
      }

      button:active {
        background: #2a4eb8;
      }

      .preview-area {
        margin-top: 30px;
        padding: 20px;
        background: #f0f0f0;
        border-radius: 6px;
        text-align: center;
      }

      .preview-title {
        font-size: 18px;
        margin-bottom: 15px;
        color: #333;
        font-weight: bold;
      }

      .preview-container {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
        gap: 20px;
        justify-items: center;
      }

      .preview-item {
        background: white;
        padding: 10px;
        border-radius: 6px;
        box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
      }

      .preview-item img {
        max-width: 100%;
        height: auto;
        border: 1px solid #ddd;
      }

      .warning {
        color: #e74c3c;
        font-size: 14px;
        margin-top: 5px;
      }

      .value-display {
        display: inline-block;
        width: 50px;
        text-align: right;
        margin-left: 10px;
        color: #4a6ee0;
        font-weight: bold;
      }

      .remove-logo {
        background: #e74c3c;
        color: white;
        border: none;
        border-radius: 3px;
        padding: 3px 8px;
        margin-left: 10px;
        cursor: pointer;
        font-size: 12px;
      }

      .remove-logo:hover {
        background: #c0392b;
      }

      .paper-type-select {
        padding: 6px;
        border-radius: 4px;
        border: 1px solid #ccc;
        width: 200px;
      }
    </style>
  </head>

  <body>
    <div class="container">
      <h1>打印水牌工具</h1>

      <div class="control-panel">
        <div class="control-group">
          <h3>基本设置</h3>
          <div>
            <label for="paperType">纸张类型</label>
            <select
              id="paperType"
              class="paper-type-select"
              onchange="changePaperType(event)"
            >
              <option value="a4">A4 (210×297mm)</option>
              <option value="a5">A5 (148×210mm)</option>
              <option value="a3">A3 (297×420mm)</option>
              <option value="b5">B5 (176×250mm)</option>
              <option value="letter">Letter (216×279mm)</option>
              <option value="legal">Legal (216×356mm)</option>
              <option value="custom">自定义</option>
            </select>
          </div>
          <div id="customPaperSettings" style="display: none">
            <div>
              <label for="paperx">纸张宽度</label>
              <input
                type="range"
                min="100"
                max="2160"
                id="paperx"
                oninput="chg(event)"
              />
              <span class="value-display" id="paperx-value">794</span>
            </div>
            <div>
              <label for="papery">纸张高度</label>
              <input
                type="range"
                min="100"
                max="3054"
                id="papery"
                oninput="chg(event)"
              />
              <span class="value-display" id="papery-value">1123</span>
            </div>
          </div>
          <div>
            <label for="fm">字体</label>
            <select id="fm" onchange="chg(event)"></select>
          </div>
          <div>
            <label for="st">样式</label>
            <select id="st" onchange="chg(event)"></select>
          </div>
        </div>

        <div class="control-group">
          <div id="mingdan">
            <h3 style="display: inline">名单</h3>
            <span>(建议全部设置完成后再选择)</span>
          </div>
          <div>
            <label for="lst">名单</label>
            <input type="file" id="lst" oninput="chg(event)" />
          </div>
          <div>
            <label for="poslx">水平位置</label>
            <input type="range" max="2160" id="poslx" oninput="chg(event)" />
            <span class="value-display" id="poslx-value">400</span>
          </div>
          <div>
            <label for="posly">垂直位置</label>
            <input type="range" max="3054" id="posly" oninput="chg(event)" />
            <span class="value-display" id="posly-value">900</span>
          </div>
          <div>
            <label for="ft">字体大小</label>
            <input
              type="range"
              min="10"
              max="500"
              id="ft"
              oninput="chg(event)"
            />
            <span class="value-display" id="ft-value">156</span>
          </div>
        </div>

        <div class="control-group">
          <h3>LOGO 1 设置</h3>
          <div>
            <label for="lg1">LOGO 1</label>
            <input type="file" id="lg1" oninput="chg(event)" />
            <button class="remove-logo" onclick="removeLogo(1)">移除</button>
          </div>
          <div>
            <label for="pos1x">水平位置</label>
            <input type="range" max="650" id="pos1x" oninput="chg(event)" />
            <span class="value-display" id="pos1x-value">50</span>
          </div>
          <div>
            <label for="pos1y">垂直位置</label>
            <input type="range" max="1100" id="pos1y" oninput="chg(event)" />
            <span class="value-display" id="pos1y-value">700</span>
          </div>
          <div>
            <label for="zoom1">缩放</label>
            <input
              type="range"
              min="0.1"
              max="2.0"
              step="0.1"
              id="zoom1"
              oninput="chg(event)"
            />
            <span class="value-display" id="zoom1-value">1.0</span>
          </div>
        </div>

        <div class="control-group">
          <h3>LOGO 2 设置</h3>
          <div>
            <label for="lg2">LOGO 2</label>
            <input type="file" id="lg2" oninput="chg(event)" />
            <button class="remove-logo" onclick="removeLogo(2)">移除</button>
          </div>
          <div>
            <label for="pos2x">水平位置</label>
            <input type="range" max="650" id="pos2x" oninput="chg(event)" />
            <span class="value-display" id="pos2x-value">220</span>
          </div>
          <div>
            <label for="pos2y">垂直位置</label>
            <input type="range" max="1100" id="pos2y" oninput="chg(event)" />
            <span class="value-display" id="pos2y-value">710</span>
          </div>
          <div>
            <label for="zoom2">缩放</label>
            <input
              type="range"
              min="0.1"
              max="2.0"
              step="0.1"
              id="zoom2"
              oninput="chg(event)"
            />
            <span class="value-display" id="zoom2-value">1.0</span>
          </div>
        </div>

        <div class="control-group">
          <h3>倒影设置</h3>
          <div>
            <label for="offsetx">水平偏移</label>
            <input
              type="range"
              max="1160"
              min="-500"
              id="offsetx"
              oninput="chg(event)"
            />
            <span class="value-display" id="offsetx-value">0</span>
          </div>
          <div>
            <label for="offsety">垂直偏移</label>
            <input
              type="range"
              max="2054"
              min="-1000"
              id="offsety"
              oninput="chg(event)"
            />
            <span class="value-display" id="offsety-value">0</span>
          </div>
        </div>
      </div>

      <div class="button-group">
        <button onclick="resets()">重置</button>
        <button onclick="prints()">打印</button>
      </div>

      <div class="preview-area">
        <div class="preview-title">预览效果</div>
        <div class="warning">
          提示：使用Chrome或Edge浏览器可获得最佳打印效果
        </div>
        <div id="preview" class="preview-container"></div>
      </div>
    </div>

    <script>
      // 初始化字体和样式选项
      const fonts = [
        "微软雅黑",
        "宋体",
        "新宋体",
        "楷体",
        "华文中宋",
        "隶书",
        "华文细黑",
        "华文琥珀",
        "华文彩云",
        "黑体",
        "仿宋",
        "方正舒体",
        "等线",
        "方正粗黑宋简体",
        "华文行楷",
      ];
      const styles = ["常规,normal", "斜体,italic", "粗体,700", "非粗体,400"];
      const fm = document.getElementById("fm"),
        st = document.getElementById("st");

      for (let f of fonts) {
        let opt = document.createElement("option");
        opt.value = f;
        opt.innerText = f;
        if (f === "微软雅黑") opt.selected = true;
        fm.appendChild(opt);
      }

      for (let s of styles) {
        let opt = document.createElement("option");
        let parts = s.split(",");
        opt.value = s;
        opt.innerText = parts[0];
        if (parts[1] === "normal") opt.selected = true;
        st.appendChild(opt);
      }

      // 初始化输入控件
      var inputs = new Map();
      for (let [k, v] of Object.entries(pos)) {
        inputs.set(k, document.getElementById(k));
        inputs.get(k).value = v;
        // 更新值显示
        if (document.getElementById(k + "-value")) {
          document.getElementById(k + "-value").textContent = v;
          if (k === "zoom1" || k === "zoom2") {
            document.getElementById(k + "-value").textContent =
              parseFloat(v).toFixed(1);
          }
        }
      }

      var preview = document.getElementById("preview");

      function updatePaperSizeDisplay() {
        const paperType = document.getElementById("paperType").value;
        const paper = paperTypes[paperType];

        // 显示当前纸张尺寸信息
        const sizeInfo = document.getElementById("paperSizeInfo");
        if (!sizeInfo) {
          // 创建尺寸信息显示元素
          const infoDiv = document.createElement("div");
          infoDiv.id = "paperSizeInfo";
          infoDiv.style.marginTop = "10px";
          infoDiv.style.fontSize = "14px";
          infoDiv.style.color = "#666";
          document.querySelector(".control-group h3").after(infoDiv);
        }

        document.getElementById(
          "paperSizeInfo"
        ).textContent = `当前尺寸: ${paper.mmWidth}×${paper.mmHeight}mm (${paper.width}×${paper.height}px)`;
      }

      // 纸张类型变更函数
      function changePaperType(event) {
        const paperType = event.target.value;

        if (paperType === "custom") {
          // 显示自定义纸张设置
          document.getElementById("customPaperSettings").style.display =
            "block";
        } else {
          // 隐藏自定义纸张设置
          document.getElementById("customPaperSettings").style.display = "none";

          // 更新纸张尺寸
          const selectedPaper = paperTypes[paperType];
          els.paperx = selectedPaper.width;
          els.papery = selectedPaper.height;

          // 更新界面显示
          document.getElementById("paperx").value = selectedPaper.width;
          document.getElementById("papery").value = selectedPaper.height;
          document.getElementById("paperx-value").textContent =
            selectedPaper.width;
          document.getElementById("papery-value").textContent =
            selectedPaper.height;
        }
        // 更新尺寸信息显示
        updatePaperSizeDisplay();
        // 重绘预览
        drawit();
      }

      // 移除Logo函数
      function removeLogo(num) {
        if (num === 1) {
          els.hasLogo1 = false;
          els.lg1.src = "";
          document.getElementById("lg1").value = "";
        } else {
          els.hasLogo2 = false;
          els.lg2.src = "";
          document.getElementById("lg2").value = "";
        }
        drawit();
      }

      // 绘制函数
      function drawit() {
        let zoom1w = els.lg1.naturalWidth * els.zoom1,
          zoom1h = els.lg1.naturalHeight * els.zoom1,
          zoom2w = els.lg2.naturalWidth * els.zoom2,
          zoom2h = els.lg2.naturalHeight * els.zoom2;

        preview.innerHTML = "";

        // 计算预览缩放比例，确保预览图不会太大
        const maxPreviewSize = 300;
        const scale = Math.min(
          maxPreviewSize / els.paperx,
          maxPreviewSize / els.papery
        );
        const previewWidth = els.paperx * scale;
        const previewHeight = els.papery * scale;

        for (let txt of els.lst) {
          if (!txt || txt.trim() === "") continue;

          if (txt.length < 3) {
            txt = txt[0] + "   " + txt[1];
          }

          let canvas = document.createElement("canvas");
          canvas.setAttribute("width", els.paperx);
          canvas.setAttribute("height", els.papery);
          canvas.style.width = previewWidth + "px";
          canvas.style.height = previewHeight + "px";
          canvas.style.border = "1px solid #ccc";

          let ctx = canvas.getContext("2d");

          // 清除画布
          ctx.clearRect(0, 0, canvas.width, canvas.height);

          // 设置字体
          ctx.font = `${els.st} ${els.wt} ${els.ft}px ${els.fm}`;
          ctx.textAlign = "center";
          ctx.textBaseline = "middle";
          ctx.fillStyle = "black";

          // 绘制正面的文字和logo
          ctx.fillText(txt, els.poslx, els.posly);

          // 只在有logo时绘制
          if (els.hasLogo1 && els.lg1.complete && els.lg1.naturalWidth > 0) {
            ctx.drawImage(els.lg1, els.pos1x, els.pos1y, zoom1w, zoom1h);
          }
          if (els.hasLogo2 && els.lg2.complete && els.lg2.naturalWidth > 0) {
            ctx.drawImage(els.lg2, els.pos2x, els.pos2y, zoom2w, zoom2h);
          }

          // 绘制倒影
          ctx.save();
          ctx.translate(canvas.width, canvas.height);
          ctx.rotate(Math.PI);
          ctx.font = `${els.st} ${els.wt} ${els.ft}px ${els.fm}`;
          ctx.textAlign = "center";
          ctx.textBaseline = "middle";
          ctx.fillText(txt, els.poslx - els.offsetx, els.posly - els.offsety);

          // 只在有logo时绘制倒影
          if (els.hasLogo1 && els.lg1.complete && els.lg1.naturalWidth > 0) {
            ctx.drawImage(
              els.lg1,
              els.pos1x - els.offsetx,
              els.pos1y - els.offsety,
              zoom1w,
              zoom1h
            );
          }
          if (els.hasLogo2 && els.lg2.complete && els.lg2.naturalWidth > 0) {
            ctx.drawImage(
              els.lg2,
              els.pos2x - els.offsetx,
              els.pos2y - els.offsety,
              zoom2w,
              zoom2h
            );
          }
          ctx.restore();

          // 创建预览项
          let previewItem = document.createElement("div");
          previewItem.className = "preview-item";

          let img = document.createElement("img");
          img.src = canvas.toDataURL("image/png");
          img.alt = txt;
          img.style.width = previewWidth + "px";
          img.style.height = previewHeight + "px";

          let caption = document.createElement("div");
          caption.textContent = txt;
          caption.style.marginTop = "10px";
          caption.style.fontWeight = "bold";

          previewItem.appendChild(img);
          previewItem.appendChild(caption);
          preview.appendChild(previewItem);
        }
      }

      // 重置函数
      function resets() {
        // 重置纸张类型为A4
        document.getElementById("paperType").value = "a4";
        document.getElementById("customPaperSettings").style.display = "none";

        // 更新纸张尺寸
        els.paperx = paperTypes.a4.width;
        els.papery = paperTypes.a4.height;

        // 更新界面显示
        document.getElementById("paperx").value = paperTypes.a4.width;
        document.getElementById("papery").value = paperTypes.a4.height;
        document.getElementById("paperx-value").textContent =
          paperTypes.a4.width;
        document.getElementById("papery-value").textContent =
          paperTypes.a4.height;

        for (let [k, v] of Object.entries(pos)) {
          els[k] = v;
          inputs.get(k).value = v;
          if (document.getElementById(k + "-value")) {
            document.getElementById(k + "-value").textContent = v;
            if (k === "zoom1" || k === "zoom2") {
              document.getElementById(k + "-value").textContent =
                parseFloat(v).toFixed(1);
            }
          }
        }
        // 重置logo状态
        els.hasLogo1 = false;
        els.hasLogo2 = false;
        els.lg1.src = "";
        els.lg2.src = "";
        document.getElementById("lg1").value = "";
        document.getElementById("lg2").value = "";

        drawit();
      }

      // 打印函数
      function prints() {
        let printWindow = window.open("", "_blank");
        let printContent = "";

        // 获取当前纸张尺寸
        const paperWidth = els.paperx;
        const paperHeight = els.papery;

        // 添加所有图片到打印窗口
        let previewImages = preview.getElementsByTagName("img");
        for (let i = 0; i < previewImages.length; i++) {
          printContent += `
                <div class="print-page">
                    <img src="${previewImages[i].src}" alt="水牌 ${
            i + 1
          }" style="width:${paperWidth}px;height:${paperHeight}px;">
                </div>
            `;
        }

        printWindow.document.write(`
            <!DOCTYPE html>
            <html>
            <head>
                <title>打印水牌 - ${paperWidth}×${paperHeight}px</title>
                <style>
                    @page {
                        size: ${paperWidth}px ${paperHeight}px;
                        margin: 0;
                    }
                    body {
                        margin: 0;
                        padding: 0;
                        display: flex;
                        flex-direction: column;
                        align-items: center;
                    }
                    .print-page {
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        width: 100%;
                        height: 100vh;
                        page-break-after: always;
                    }
                    .print-page:last-child {
                        page-break-after: auto;
                    }
                    img {
                        max-width: 100%;
                        max-height: 100%;
                        object-fit: contain;
                    }
                </style>
            </head>
            <body>
                ${printContent}
            </body>
            </html>
        `);

        printWindow.document.close();

        // 延迟打印以确保图片加载完成
        setTimeout(() => {
          printWindow.print();
          // 检查浏览器是否支持onafterprint
          if (typeof printWindow.onafterprint !== "undefined") {
            printWindow.onafterprint = function () {
              setTimeout(() => {
                printWindow.close();
              }, 100);
            };
          } else {
            // 如果不支持onafterprint，直接延迟关闭
            setTimeout(() => {
              printWindow.close();
            }, 1000);
          }
        }, 500);
      }

      // 处理变化事件
      function chg(ev) {
        let e = ev.target;

        // 更新值显示
        if (e.type === "range" && document.getElementById(e.id + "-value")) {
          document.getElementById(e.id + "-value").textContent = e.value;
          if (e.id === "zoom1" || e.id === "zoom2") {
            document.getElementById(e.id + "-value").textContent = parseFloat(
              e.value
            ).toFixed(1);
          }
        }

        // 如果是纸张尺寸调整，检查是否在自定义模式下
        if (e.id === "paperx" || e.id === "papery") {
          if (document.getElementById("paperType").value !== "custom") {
            // 自动切换到自定义模式
            document.getElementById("paperType").value = "custom";
            document.getElementById("customPaperSettings").style.display =
              "block";
          }

          // 更新els中的值
          els[e.id] = parseInt(e.value);
        }

        if (e.id === "lst") {
          let reader = new FileReader();
          reader.onload = () => {
            els.lst = reader.result
              .split("\r\n")
              .filter((name) => name.trim() !== "");
            e.value = ""; //避免后续同名文件不触发
            drawit();
          };
          reader.readAsText(e.files[0]);
        } else if (e.id.startsWith("lg")) {
          let reader = new FileReader();
          reader.onload = () => {
            els[e.id].src = reader.result;
            // 标记已选择logo
            if (e.id === "lg1") els.hasLogo1 = true;
            if (e.id === "lg2") els.hasLogo2 = true;
            els[e.id].onload = drawit;
            e.value = "";
          };
          reader.readAsDataURL(e.files[0]);
        } else if (e.id === "st") {
          if (st.selectedIndex > 1) {
            els.wt = e.value.split(",")[1];
          } else {
            els.st = e.value.split(",")[1];
          }
          drawit();
        } else {
          els[e.id] = e.value;
          drawit();
        }
      }

      // 初始绘制
      window.onload = function () {
        initPaperTypeSelect();
        document.getElementById("paperType").value = "a4";
        // 不设置默认logo图片，避免占位图显示
        drawit();
      };
    </script>
  </body>
</html>
